import ViewBase from "./ViewBase";
import { UI_Cache_Type, UI_Config } from "./UI_Config";
import ResourcesManager from "./ResourceManager";
import { Logger } from "./Logger";
import { Sprite, Node, Prefab, instantiate } from "cc";

const CdCheckUiTime: number = 30 * 1000

export default class UIManager {

    public static instance: UIManager = new UIManager();

    //单例的面板
    private singleList: Map<UI_Config, ViewBase> = new Map<UI_Config, ViewBase>();


    private showList: Map<number, ViewBase> = new Map<number, ViewBase>(); //正在展示的界面
    private cacheList: Map<UI_Config, number> = new Map<UI_Config, number>(); //缓存的列表
    private onlyId: number = 0;


    /**基础层 */
    private baseRoot: Node;
    /**顶层 */
    private topRoot: Node;

    private loadingIcon: Node;

    private nextCheckUiTime: number = 0;

    public darkLayer: Node;

    public keyboradView: ViewBase;


    public init(UIRoot: Node) {
        this.baseRoot = UIRoot.getChildByName("baseRoot");
        this.topRoot = UIRoot.getChildByName("topRoot");
        this.loadingIcon = UIRoot.getChildByName("loadingIcon");
        this.darkLayer = UIRoot.getChildByName("darkLayer");
        this.darkLayer.active = false;
        this.hideLoadingIcon()
    }

    public showLoadingIcon(isShowIcon: boolean = true) {
        this.loadingIcon.active = isShowIcon;
        this.loadingIcon.getChildByName("icon").active = isShowIcon;
    }

    public hideLoadingIcon() {
        this.loadingIcon.active = false;
    }

    public createView(uiConfig: UI_Config, callback?: Function) {
        ResourcesManager.instance.loadPrefab(uiConfig, (prefab: Prefab) => {
            let item: Node = instantiate(prefab);
            let view: ViewBase = item.getComponent(ViewBase);
            if (!view) {
                Logger.warn(uiConfig.path, "没有添加ViewBase组件")
            } else {
                view.onlyId = this.onlyId++;
                callback && callback(view);
            }
        });
    }

    public hadShowView(uiConfig: UI_Config) {
        if (this.singleList.has(uiConfig)) {
            let view: ViewBase = this.singleList.get(uiConfig);
            if (view.node.active) {
                return true
            }
        }
    }

    public showView(uiConfig: UI_Config, callback?: Function, ...optionalParams: any[]) {
        Logger.log("showView==", uiConfig)
        if (this.singleList.has(uiConfig)) {
            this.singleList.forEach((value: ViewBase) => {
                value.node.setSiblingIndex(0)
            });
            this.showList.forEach((value: ViewBase, id: number) => {
                value.node.setSiblingIndex(0)
            });
            let view: ViewBase = this.singleList.get(uiConfig);
            this.showList.set(view.onlyId, view);
            view.onInitBase(uiConfig, ...optionalParams);
            view.node.active = true;
            view.node.setSiblingIndex(view.node.parent.children.length + 1)
            callback && callback(view);
        }
        else {
            ResourcesManager.instance.loadPrefab(uiConfig, (prefab: Prefab) => {
                this.showList.forEach((value: ViewBase, id: number) => {
                    value.node.setSiblingIndex(0)
                });
                let item: Node = instantiate(prefab);
                let view: ViewBase = item.getComponent(ViewBase);
                if (!view) {
                    Logger.warn(uiConfig.path, "没有添加ViewBase组件")
                } else {
                    view.onlyId = this.onlyId++;
                    let showTimes: number = 0;
                    if (this.cacheList.has(uiConfig)) {
                        showTimes = this.cacheList.get(uiConfig);
                    }
                    showTimes++;
                    this.cacheList.set(uiConfig, showTimes);

                    item.setPosition(0, 0);
                    view.onInitBase(uiConfig, ...optionalParams);
                    item.parent = this.baseRoot;
                    item.active = true
                    view.node.setSiblingIndex(view.node.parent.children.length)
                    this.showList.set(view.onlyId, view);
                    if (uiConfig.isSingle) { //单例才缓存起来
                        this.singleList.set(uiConfig, view);
                    }
                    callback && callback(view);
                }
            });
        }
    }

    /**
   * 设置为顶层UI
   * @param name 页面名
   */
    public setTopUI(viewBase: ViewBase) {
        viewBase.node.parent = this.topRoot;
        viewBase.node.setSiblingIndex(this.topRoot.children.length)
    }

    private onFrameUpdate(now: number) {
        if (now >= this.nextCheckUiTime) {
            this.cacheList.forEach((value: number, key: UI_Config) => {
                if (key.cacheType == UI_Cache_Type.someTimes) {
                    if (value <= 0) {
                        ResourcesManager.instance.release(key.path)
                    }
                }
            });
            this.nextCheckUiTime = now + CdCheckUiTime;
        }
    }

    //关闭单例的界面
    public closeSingleView(uiConfig: UI_Config) {
        if (uiConfig.isSingle) {
            let view: ViewBase = this.singleList.get(uiConfig);
            if (view) {
                view.closeView()
                // Logger.warn("关闭存在single view", uiConfig, this.singleList)
            } else {
                // Logger.warn("关闭不存在single view", uiConfig, this.singleList)
            }
        }
        else {
            Logger.warn("关闭不是single view", uiConfig)
        }
    }

    public closeButView(uiConfig: UI_Config) {
        this.showList.forEach((value: ViewBase, id: number) => {
            // value.closeView();
            if (value.uiConfig != uiConfig) {
                value.closeView()
            }
        });
    }

    public closeView(view: ViewBase) {
        // Logger.log("closeView=", view)
        this.showList.delete(view.onlyId);
        if (view.uiConfig.cacheType == UI_Cache_Type.someTimes ||
            view.uiConfig.cacheType == UI_Cache_Type.noCache) {
            let showTimes: number = 0;
            if (this.cacheList.has(view.uiConfig)) {
                showTimes = this.cacheList.get(view.uiConfig);
                showTimes--;
                if (showTimes < 0) {
                    showTimes = 0
                }
                this.cacheList.set(view.uiConfig, showTimes);
            }
            if (view.uiConfig.isSingle) {
                this.singleList.delete(view.uiConfig);
            }
            if (view.uiConfig.cacheType == UI_Cache_Type.noCache) {
                ResourcesManager.instance.release(view.uiConfig.path)
            }
        }
        // Logger.log("closeView=childrenCount", this.baseRoot.childrenCount)
        // Logger.log("closeView=baseRoot", this.baseRoot.children)
    }

    public releaseForce(view: ViewBase) {
        this.showList.delete(view.onlyId);
        this.singleList.delete(view.uiConfig);
        try {
            ResourcesManager.instance.release(view.uiConfig.path)
        } catch (error) {
            Logger.error("releaseForce", error, view, view.uiConfig)
        }
    }


    public closeAllView() {
        this.showList.forEach((value: ViewBase, id: number) => {
            value.closeView();
        });
        this.showList.clear();

        // Logger.log("closeAllView==showList===", this.showList)
        // Logger.log("closeAllView====singleList=", this.singleList)
        // Logger.log("closeAllView====children=", this.baseRoot.children)
        // this.singleList.clear();
        // this.topRoot.removeAllChildren();
        // this.baseRoot.removeAllChildren();
        this.loadingIcon.active = false;
    }

    public clear() {
        this.closeAllView();
        this.singleList.clear();
    }
}
